#ifndef MOONLIGHT_OHOS_AVUTILS_H
#define MOONLIGHT_OHOS_AVUTILS_H

#include <multimedia/player_framework/native_avbuffer_info.h>
#include <multimedia/player_framework/native_averrors.h>
#include <multimedia/player_framework/native_avformat.h>
#include <memory>
#include <functional>
#include <ohaudio/native_audiostream_base.h>

#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN  0x0
#define LOG_TAG     "AVUtils"
#include <hilog/log.h>


#define AV_CALL_OR_ELSE(expr, otherwise) \
    if (auto avCallResult = (expr); avCallResult != AV_ERR_OK) { \
        OH_LOG_ERROR(LOG_APP, "AV call %{public}s failed with %{public}d", #expr, avCallResult); \
        otherwise; \
    }


struct AVUtils {

    struct AVFormatDeleter {
        void operator()(OH_AVFormat *fmt);
    };
    static std::unique_ptr<OH_AVFormat, AVFormatDeleter> makeAVFormat(const std::function<OH_AVFormat*()> &ctor);

    struct AudioStreamBuilderDeleter {
        void operator()(OH_AudioStreamBuilder *bld);
    };
    static std::unique_ptr<OH_AudioStreamBuilder, AudioStreamBuilderDeleter> makeAudioStreamBuilder(OH_AudioStream_Type type);


    struct [[gnu::packed]] PtsAsBufferCtx {
        uint32_t uuid = 0;
        int32_t belongToFrame : 31 = 0;
        unsigned __magicBitToInvalidatePtsFuntionality : 1 = 1;
    };
    static_assert(sizeof(PtsAsBufferCtx) == sizeof(OH_AVCodecBufferAttr::pts));
    static_assert(offsetof(PtsAsBufferCtx, uuid) == 0);

};

#endif //MOONLIGHT_OHOS_AVUTILS_H
